/*-------------------------------------------------------------------------
 *
 * walsender_private.h
 *	  从 replication/walsender.c 的私有定义。
 *
 * Portions Copyright (c) 2010-2022, PostgreSQL Global Development Group
 *
 * src/include/replication/walsender_private.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef _WALSENDER_PRIVATE_H
#define _WALSENDER_PRIVATE_H

#include "access/xlog.h"
#include "nodes/nodes.h"
#include "replication/syncrep.h"
#include "storage/latch.h"
#include "storage/shmem.h"
#include "storage/spin.h"

typedef enum WalSndState
{
	WALSNDSTATE_STARTUP = 0,
	WALSNDSTATE_BACKUP,
	WALSNDSTATE_CATCHUP,
	WALSNDSTATE_STREAMING,
	WALSNDSTATE_STOPPING
} WalSndState;

/*
 * 每个walsender在共享内存中都有一个WalSnd结构。
 *
 * 该结构由其'mutex'自旋锁字段保护，除非某些成员仅由walsender进程本身写入，因此该进程可以在不持有自旋锁的情况下读取这些成员。 pid和needreload在所有访问时始终需要持有自旋锁。
 */
typedef struct WalSnd
{
	pid_t		pid;			/* 该walsender的PID，若未激活则为0 */

	WalSndState state;			/* 该walsender的状态 */
	XLogRecPtr	sentPtr;		/* WAL已发送到这一点 */
	bool		needreload;		/* 当前打开的文件是否需要重新加载？ */

	/*
	 * 已被备用端写入、刷新和应用的xlog位置。这些可能会无效，如果备用端尚未提供值。
	 */
	XLogRecPtr	write;
	XLogRecPtr	flush;
	XLogRecPtr	apply;

	/* 测量的延迟时间，或-1表示未知/无。 */
	TimeOffset	writeLag;
	TimeOffset	flushLag;
	TimeOffset	applyLag;

	/*
	 * 此WALSender管理的备用的优先顺序，如在synchronous_standby_names中列出，或如果未列出则为0。
	 */
	int			sync_standby_priority;

	/* 保护上面显示的共享变量。 */
	slock_t		mutex;

	/*
	 * 指向walsender的闩锁的指针。后端用于在walsender有工作要做时唤醒该walsender。如果walsender未激活，则为NULL。
	 */
	Latch	   *latch;

	/*
	 * 从备用收到的最后一条消息的时间戳。
	 */
	TimestampTz replyTime;
} WalSnd;

extern PGDLLIMPORT WalSnd *MyWalSnd;

/* 整个数据库集群只有一个WalSndCtl结构 */
typedef struct
{
	/*
	 * 每种请求类型都有一个队列的同步复制队列。
	 * 由SyncRepLock保护。
	 */
	SHM_QUEUE	SyncRepQueue[NUM_SYNC_REP_WAIT_MODE];

	/*
	 * 队列头的当前位置。所有等待者应具有一个跟随此值的waitLSN。由SyncRepLock保护。
	 */
	XLogRecPtr	lsn[NUM_SYNC_REP_WAIT_MODE];

	/*
	 * 是否定义了任何同步备用？等待的后端无法安全地重新加载配置文件，因此检查点根据需要更新此值。
	 * 由SyncRepLock保护。
	 */
	bool		sync_standbys_defined;

	WalSnd		walsnds[FLEXIBLE_ARRAY_MEMBER];
} WalSndCtlData;

extern PGDLLIMPORT WalSndCtlData *WalSndCtl;


extern void WalSndSetState(WalSndState state);

/*
 * 用于解析复制文法的内部函数，在repl_gram.y和repl_scanner.l中
 */
extern int	replication_yyparse(void);
extern int	replication_yylex(void);
extern void replication_yyerror(const char *str) pg_attribute_noreturn();
extern void replication_scanner_init(const char *query_string);
extern void replication_scanner_finish(void);
extern bool replication_scanner_is_replication_command(void);

extern PGDLLIMPORT Node *replication_parse_result;

#endif							/* _WALSENDER_PRIVATE_H */
